<?php


namespace BoojasrFramework\Obs;


class Observable
{

    private $_value = [];

    public function __get($name)
    {
        return $this->_value[$name]??null;
    }

    public function __set($name, $value)
    {
        $isNotify = false;
        if ($this->_value[$name] != $value){
            $isNotify = true;
        }
        $this->_value[$name] = $value;
        if ($isNotify){
            $this->notify();
        }
        return $this;
    }

    /**
     * 通知观察者
     * @return void
     */
    public function notify()
    {
        foreach ($this->_observers as $v) {
            $v->receiveNotify($this->_value);
        }
    }

    /**
     * 观察者
     * @var ObserverInterface[]
     */
    private $_observers = [];

    /**
     * 附加观察者
     * @return void
     */
    public function addObserver($observer)
    {
        if (!$this->findObserverByName($observer->getName())) {
            $this->_observers[$observer->getName()] = $observer;
        }
    }

    /**
     * 解除观察者
     * @param ObserverInterface $observer
     * @return bool
     */
    public function removeObserver($observer)
    {
        if (isset($this->_observers[$observer->getName()])) {
            unset($this->_observers[$observer->getName()]);
            return true;
        }
        return false;
    }

    /**
     * @param $name
     * @return bool
     */
    public function removeObserverByName($name)
    {
        $observer = $this->findObserverByName($name);
        if ($observer){
            return $this->removeObserver($observer);
        }
        return false;
    }

    /**
     * @param $name
     * @return ObserverInterface|null
     */
    public function findObserverByName($name)
    {
        if (isset($this->_observers[$name])){
            return $this->_observers[$name];
        }
        return null;
    }
}
